﻿using PRO.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
using PRO.Common;

namespace PRO.ORM
{
    /// <summary>
    /// 根据实体类创建数据库表
    /// </summary>
    public static class EntityCreateTable
    {
        /// <summary>
        /// 根据当前实体类在数据库创建对应的表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static bool CreateTable<T>(this T entity) where T : BaseEntity
        {
            List<EntityAttributeInfo> feilds = new List<EntityAttributeInfo>();
            feilds = EntityAttributeLib.GetProperties(entity, feilds, null);
            string tablename = EntityAttributeLib.GetTableName(entity);
            //if (!CheckDataTableIsCreated(tablename))
            //{
            if (feilds.Count > 0 && !string.IsNullOrWhiteSpace(tablename))
            {
                StringBuilder sql = new StringBuilder();
                sql.AppendFormat(" IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[{0}]') AND type in (N'U'))  \r\n BEGIN  \r\n", tablename);
                sql.AppendFormat("create table [dbo].[{0}]\r\n(\r\n", tablename);
                foreach (EntityAttributeInfo item in feilds)
                {
                    sql.AppendFormat(" [{0}] [{1}]{2} {3} {4} {5},\r\n ", item.Feild, item.SqlDbType.ToString(), GetFeildLen(item.SqlDbType, item.Len), (item.PrimaryKey) ? "PRIMARY KEY IDENTITY(1,1)" : "", (item.PrimaryKey || item.NotNull) ? "not null" : "", GetDefaultValue(item.SqlDbType, item.DefaultValue));
                }
                sql.Append("\r\n)\r\n end");
                //if (Convert.ToBoolean(DbHelper.ExecuteNonQuery(CommandType.Text, sql.ToString())))
                //{
                //    return CreaterDataTableCreatedLock(tablename);
                //}
                //else
                //    return false;
                return Convert.ToBoolean(DbHelper.ExecuteNonQuery(CommandType.Text, sql.ToString()));
            }
            else
                throw new Exception("表名和字段不能为空！");
            //}
            //else
            //    return true;
        }
        /// <summary>
        /// 创建锁定文件
        /// </summary>
        /// <param name="tablename"></param>
        /// <returns></returns>
        private static bool CreaterDataTableCreatedLock(string tablename)
        {
            string filename = null;
            HttpContext context = HttpContext.Current;
            if (context != null)
            {
                filename = context.Server.MapPath("/Lock/" + tablename + ".DataTableCreated");
            }
            else
            {
                filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "/Lock/" + tablename + ".DataTableCreated");
            }
            Utils.CreateFile(filename, "The " + tablename + " was created");
            return true;
        }
        /// <summary>
        /// 检查数据是否已经创建过了
        /// </summary>
        /// <param name="tablename"></param>
        /// <returns></returns>
        private static bool CheckDataTableIsCreated(string tablename)
        {
            string filename = null;
            HttpContext context = HttpContext.Current;
            if (context != null)
            {
                filename = context.Server.MapPath("/Lock/" + tablename + ".DataTableCreated");
            }
            else
            {
                filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "/Lock/" + tablename + ".DataTableCreated");
            }
            if (File.Exists(filename))
                return true;
            else
                return false;
        }
        private static string GetFeildLen(SqlDbType t,int len)
        {
            string str = null;
            if (len > 0)
            {
                switch (t)
                {
                    case SqlDbType.Int:
                    case SqlDbType.DateTime:
                    case SqlDbType.Bit:
                    case SqlDbType.Text:
                    case SqlDbType.Money:
                    case SqlDbType.NText:
                    case SqlDbType.Image:
                    case SqlDbType.Xml:
                        str = "";
                        break;
                    case SqlDbType.Decimal:
                        str = string.Format("({0},{1})", len, 2);
                        break;
                    default:
                        str = string.Format("({0})", len);
                        break;
                }
            }
            return str;
        }
        private static string GetDefaultValue(SqlDbType t, object value)
        {
            string str = null;
            if (value != null)
            {
                switch (t)
                {
                    case SqlDbType.Bit:
                        if(Convert.ToBoolean(value.ToString()))
                            str = "default((1))";
                        else
                            str = "default((0))";
                        break;
                    default:
                        str = string.Format("default(({0}))", value.ToString());
                        break;
                }
            }
            return str;
        }
    }
}
